#include "Rp2SkinningEffect.h"

using namespace Rp2;

RP2_IMPLEMENT_RTTI(Rp2, SkinningEffect, LightingMaterialEffect);
RP2_IMPLEMENT_DEFAULT_NAME_ID(SkinningEffect, LightingMaterialEffect);

//---------------------------------------------------------------------------------------------------
SkinningEffect::SkinningEffect(const std::string& rkTextureName)
	:LightingMaterialEffect(rkTextureName)
{

}
//---------------------------------------------------------------------------------------------------
SkinningEffect::~SkinningEffect()
{
}
//---------------------------------------------------------------------------------------------------
void SkinningEffect::Configure()
{
    if (m_kLights.size() == 0)
    {
        SetPassQuantity(1);
        m_kVShader[0] = new VertexShader("Texture");
        m_kPShader[0] = new PixelShader("Texture");
		m_kPShader[0]->SetTexture(0, m_kTexName);
        return;
    }

	m_kVShader[0] = new VertexShader("Skinning_w2_L1d");
	m_kPShader[0] = new PixelShader("Skinning_w2_L1d");
	

	for (int i = 0; i < 24; i++)
	{
		m_akMatrix[i][0] = 1.0f;
		m_akMatrix[i][1] = 0.0f;
		m_akMatrix[i][2] = 0.0f;
		m_akMatrix[i][3] = 0.0f;
		m_akMatrix[i][4] = 0.0f;
		m_akMatrix[i][5] = 1.0f;
		m_akMatrix[i][6] = 0.0f;
		m_akMatrix[i][7] = 0.0f;
		m_akMatrix[i][8] = 0.0f;
		m_akMatrix[i][9] = 0.0f;
		m_akMatrix[i][10] = 1.0f;
		m_akMatrix[i][11] = 0.0f;
		if (i < 10)
		{	
			char acName[] = "SkinningMatrix[*]";
			acName[15] = '0' + i;
			ConnectVShaderConstant(0, acName, m_akMatrix[i]);
		}
		else
		{
			char acName[] = "SkinningMatrix[**]";
			acName[15] = '0' + i/10;
			acName[16] = '0' + i%10;
			ConnectVShaderConstant(0, acName, m_akMatrix[i]);
		}
	}

// 	// back root
// 	Vector3f Tr0(0.0f, 8.513f, +0.03f);
// 	Quaternionf Qr0(0.432313f,-0.559558f,-0.432313f,0.559558f);
// 	Matrix3f Or0;
// 	Qr0.ToRotationMatrix(Or0);
// 	Vector3f Tw0 = Tr0;
// 	Matrix3f Ow0 = Or0;
// 	Matrix3f R0 = Matrix3f::IDENTITY;
// 
// 	// pelvis
// 	Vector3f Tr1(1.06521f,0,0);
// 	Quaternionf Qr1(0,0.973912f,-0.226926f,0);
// 	Matrix3f Or1;
// 	Qr1.ToRotationMatrix(Or1);
// 	Vector3f Tw1 = Tw0 + Tr1*Ow0;
// 	Matrix3f Ow1 = Or1 * Ow0;	
// 	Matrix3f R1;
// 	Quaternionf(0.979459f,-0,-0,-0.201643f).ToRotationMatrix(R1);
// 	Matrix3f R1w = Ow1.Inverse() * R1 * Ow1;
// 
// 	// lower back
// 	Vector3f Tr2(1.66987f,0,0);
// 	Quaternionf Qr2(0,0.99851f,-0.0545638f,0);
// 	Matrix3f Or2;
// 	Qr2.ToRotationMatrix(Or2);
// 	// relative update
// 	Vector3f Tr2n = Tr2 * R1;
// 	Matrix3f Or2n = Or2 * R1;
// 	Vector3f Tw2 = Tw1 + Tr2n*Ow1;
// 	Matrix3f Ow2 = Or2n * Ow1;
// 	Matrix3f R2 = Matrix3f::IDENTITY;
// 	Matrix3f R1r2 = Ow2*R1w*Ow2.Inverse();
// 
// 	// mid back
// 	Vector3f Tr3(1.44032f,0,-0);
// 	Quaternionf Qr3(0.99982f,-0,-0,0.018988f);
// 	Matrix3f Or3;
// 	Qr3.ToRotationMatrix(Or3);
// 	Vector3f Tw3 = Tw2 + Tr3*Ow2;
// 	//Tw3.Print();
// 	Matrix3f Ow3 = Or3 * Ow2;
// 	//Ow3.Print();
//  	Matrix3f R3;
// 	Quaternionf(0.909953f,-0,-0,-0.414712f).ToRotationMatrix(R3);
// 	Matrix3f R3w = Ow3.Inverse() * R3 * Ow3;
//  	Matrix3f R1r3 = Ow3*R1w*Ow3.Inverse();
// 
// 	// upper back
// 	Vector3f Tr4(1.21183f,0,-0);
// 	Quaternionf Qr4(0.993385f,-0,-0,0.114831f);
// 	Matrix3f Or4;
// 	Qr4.ToRotationMatrix(Or4);
// 	// relative update
// 	Vector3f Tr4n = Tr4 * R3;
// 	Matrix3f Or4n = Or4 * R3;
// 	Vector3f Tw4 = Tw3 + Tr4n*Ow3; // good
// 	Tw4.Print();
// 	Matrix3f Ow4 = Or4n * Ow3; // good
// 	Ow4.Print();
// 	Matrix3f R4 = Matrix3f::IDENTITY;
//  	Matrix3f R1r4 = Ow4*R1w*Ow4.Inverse();
// 	Matrix3f R3r4 = Ow4*R3w*Ow4.Inverse();
// 
// 	Matrix4f G04,G14,G24,G34,G44;
// 	Matrix3f G0,G1,G2,G3,G4;
// 	Vector3f T0,T1,T2,T3,T4;
// 	// mat 0 at back root
// 	G0 = Ow0.Transpose() * R0 * Ow0;
// 	T0 = Tw0 - Tw0*G0;
// 	G04[0] = G0[0];		G04[1] = G0[1];		G04[2] = G0[2];		G04[3] = 0;
// 	G04[4] = G0[3];		G04[5] = G0[4];		G04[6] = G0[5];		G04[7] = 0;
// 	G04[8] = G0[6];		G04[9] = G0[7];		G04[10] = G0[8];	G04[11] = 0;
// 	G04[12] = T0.X();	G04[13] = T0.Y();	G04[14] = T0.Z();	G04[15] = 1.0f;
// 	G04 = G04.Transpose();
// 	for (int i = 0; i < 12; i++)
// 	{
// 		m_akMatrix[0][i] = G04[i];
// 	}
// 
// 	// mat 1 at pelvis
// 	G1 = Ow1.Transpose() * R1 * Ow1;
// 	T1 = Tw1 - Tw1*G1;
// 	G14[0] = G1[0];		G14[1] = G1[1];		G14[2] = G1[2];		G14[3] = 0;
// 	G14[4] = G1[3];		G14[5] = G1[4];		G14[6] = G1[5];		G14[7] = 0;
// 	G14[8] = G1[6];		G14[9] = G1[7];		G14[10] = G1[8];	G14[11] = 0;
// 	G14[12] = T1.X();	G14[13] = T1.Y();	G14[14] = T1.Z();	G14[15] = 1.0f;
// 	G14 = G14.Transpose();
// 	for (int i = 0; i < 12; i++)
// 	{
// 		m_akMatrix[1][i] = G14[i];
// 	}
// 
// 	// mat 2 at lower back
// 	G2 = Ow2.Transpose() * R1r2 * Ow2;
// 	T2 = Tw2 - Tw2*G2;
// 	G24[0] = G1[0];		G24[1] = G2[1];		G24[2] = G2[2];		G24[3] = 0;
// 	G24[4] = G2[3];		G24[5] = G2[4];		G24[6] = G2[5];		G24[7] = 0;
// 	G24[8] = G2[6];		G24[9] = G2[7];		G24[10] = G2[8];	G24[11] = 0;
// 	G24[12] = T2.X();	G24[13] = T2.Y();	G24[14] = T2.Z();	G24[15] = 1.0f;
// 	G24 = G24.Transpose();
// 	for (int i = 0; i < 12; i++)
// 	{
// 		m_akMatrix[2][i] = G14[i];
// 	}
// 
// 	// mat 3 at mid back
// 	G3 = Ow3.Transpose() * R3 * Ow3;
// 	T3 = Tw3 - Tw3*G3;
// 	G34[0] = G1[0];		G34[1] = G3[1];		G34[2] = G3[2];		G34[3] = 0;
// 	G34[4] = G3[3];		G34[5] = G3[4];		G34[6] = G3[5];		G34[7] = 0;
// 	G34[8] = G3[6];		G34[9] = G3[7];		G34[10] = G3[8];	G34[11] = 0;
// 	G34[12] = T3.X();	G34[13] = T3.Y();	G34[14] = T3.Z();	G34[15] = 1.0f;
// 	G34 = G14.Transpose() * G34;
// 	G34 = G34.Transpose();
// 	for (int i = 0; i < 12; i++)
// 	{
// 		m_akMatrix[3][i] = G34[i];
// 	}
// 
// 	// mat 4 at upper back
// 	G4 = Ow4.Transpose() * R1r4 * R3r4 * Ow4;
// 	T4 = Tw4 - Tw4*G4;
// 	G44[0] = G1[0];		G44[1] = G4[1];		G44[2] = G4[2];		G44[3] = 0;
// 	G44[4] = G4[3];		G44[5] = G4[4];		G44[6] = G4[5];		G44[7] = 0;
// 	G44[8] = G4[6];		G44[9] = G4[7];		G44[10] = G4[8];	G44[11] = 0;
// 	G44[12] = T4.X();	G44[13] = T4.Y();	G44[14] = T4.Z();	G44[15] = 1.0f;
// 	//G44 = G14.Transpose() * G34.Transpose();
// 	G44 = G34;
// 	for (int i = 0; i < 12; i++)
// 	{
// 		m_akMatrix[4][i] = G44[i];
// 		m_akMatrix[5][i] = G44[i];
// 		m_akMatrix[6][i] = G44[i];
// 		m_akMatrix[7][i] = G44[i];
// 		m_akMatrix[8][i] = G44[i];
// 	}

}
//---------------------------------------------------------------------------------------------------